#ifndef BASE_FILE_H
#define BASE_FILE_H

#include <memory>
#include <fstream>
#include <string>
#include <stdexcept>
#include <sstream>
#include <unistd.h>

#include<sys/stat.h>

namespace base
{
namespace utils
{

namespace file
{
enum class FileMode
{
    EXISTS = 0,//存在
    EXECUTE = 1,//执行
    WRITE = 2,//写
    READ = 4//读
};
enum OpenModeFlag
{
    Append = 1L << 0,
    Ate = 1L << 1,
    Binary = 1L << 2,
    ReadOnly = 1L << 3,
    WriteOnly = 1L << 4,
    ReadWrite = ReadOnly | WriteOnly,
    Truncate = 1L << 5
};
}
/**
 * 文件处理基础类
 *
 * @author: haitao.lin
 */
class BaseFile
{
public:
    /**
     * 检查文件是否存在
     */
    static bool exists(const std::string &filePath);

    /**
     * 检查指定文件的指定属性，包括是否存在、是否可读、是否可写、是否有权限执行
     */
    static bool checkFileMode(const std::string &filePath, base::utils::file::FileMode mode);

    /**
     * 给指定文件赋予权限，同chmod指令
     */
    static bool chmodFile(const std::string &filePath, int mode);

public:
    virtual ~BaseFile();

    /**
     * 打开文件，返回是否成功打开，mode表示打开方式
     */
    bool open(file::OpenModeFlag mode);
    bool open(std::ios_base::openmode mode);

    /**
     * 关闭文件流
     */
    void close();

    /**
     * 设置文件的开始读取偏移
     */
    void seekInputPosition(std::size_t offsetPosition, std::ios_base::seekdir position = std::ios::beg);

    /**
     * 是否已经读到end，可用此方法判断文件是否已经读完
     */
    bool endOfFile() const;

    /**
     * 获取当前处理的文件名称
     */
    std::string getFileName() const;

protected:
    explicit BaseFile(const std::string &file_name);

protected:
    std::fstream file_stream_;
    std::string file_name_;
};

}
}

#endif //BASE_FILE_H
